//
//  MyNotification.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/3/5.
//

import Foundation
import SwiftUI
/**
 原本写法
 发送     NotificationCenter.default.post(name: .updateDiary, object: bean)
 接收
 .onAppear {
 NotificationCenter.default.addObserver(forName: .updateDiary, object: nil, queue: .main) { notification in
 if let bean = notification.object as? AddDiaryView {
 self.currentPerson = bean
 }
 }
 }
 .onDisappear {
 NotificationCenter.default.removeObserver(self, name: .updateDiary, object: nil)
 }
 */

/// 定义通知名称
extension Notification.Name {
    static let updateDiary = Notification.Name("updateDiaryNotification") //更新日记 DiaryBean 格式
    static let addDiary = Notification.Name("addDiaryNotification")//添加日记 DiaryBean 格式
    static let addChat = Notification.Name("addChatNotification")//添加聊天 ChatBean 格式
    static let searchChat = Notification.Name("searchChatNotification")//搜索聊天，String id格式
    static let delDiary = Notification.Name("delDiaryNotification")//删除日记。DiaryBean 格式
    static let aiDiary = Notification.Name("aiDiaryNotification")//ai日记  //String格式
    static let buyVoice = Notification.Name("buyVoiceNotification")//购买音色 Bool格式
    static let updateAiRole = Notification.Name("updateAiRoleNotification")//ai角色刷新 Bool格式
    static let selectAiRole = Notification.Name("selectAiRoleNotification")//ai角色选择 Bool格式
    static let push = Notification.Name("pushNotification")//推送通知 Bool格式
    static let background = Notification.Name("backgroundNotification")//进入后台通知 Bool格式。true为进入后台，false则返回前台
    static let bindAccount = Notification.Name("bindAccountNotification")//绑定第三方账号 (String,String)格式,(绑定类型，id)
    static let addComment = Notification.Name("addCommentNotification") //添加评论 DiaryCommentBean 格式
    static let updateComment = Notification.Name("updateCommentNotification") //添加评论 DiaryCommentBean 格式
    static let showComment = Notification.Name("showCommentNotification") //展开评论 (DiaryBean,String) 格式 (日记，ai的id)
    static let emojiPicture = Notification.Name("emojiPictureNotification") //表情包。EmojiPictureBean 格式
    static let updateBubble = Notification.Name("updateBubbleNotification")//更新了气泡 Bool
    static let updateBubbleComment = Notification.Name("updateBubbleCommentNotification")//更新了气泡 DiaryBean
    static let refreshHomeChat = Notification.Name("refreshHomeChatNotification")//刷新homeChat Bool
    static let refreshCustomItem = Notification.Name("refreshCustomItemNotification")//刷新自定义的api的item

}

// 存储每个 ObservableObject 的观察者
private var observers: [ObjectIdentifier: [Notification.Name: NSObjectProtocol]] = [:]

// 带通知的ObservableObject
class NotificationObservableObject: ObservableObject {
    //处理了弱引用问题，避免每个地方都有写弱引用
    /**
     self.addObserve(name: .delDiary) { [weak self] (bean: DiaryBean) in
         guard let self = self else { return }
     */
    func addObserve<T: AnyObject, U>(_ target: T, _ name: Notification.Name, action: @escaping (T, U) -> Void) {
          let key = ObjectIdentifier(self)
          if observers[key]?.keys.contains(name) == true {
              // 如果已经存在该通知的观察者，则不重复添加
              return
          }
          let observer = NotificationCenter.default.addObserver(forName: name, object: nil, queue: .main) { [weak target] notification in
              if let typedObject = notification.object as? U, let target = target {
                  action(target, typedObject)
              }
          }
          if var existingObservers = observers[key] {
              existingObservers[name] = observer
              observers[key] = existingObservers
          } else {
              observers[key] = [name: observer]
          }
      }
    
    func removeObserve() {
        let key = ObjectIdentifier(self)
        if let existingObservers = observers[key] {
            existingObservers.forEach { _, observer in
                NotificationCenter.default.removeObserver(observer)
            }
            observers.removeValue(forKey: key)
        }
    }

    deinit {
        let className = String(describing: Self.self)
        showLog("yxw", "\(className) 执行销毁")
        removeObserve()
    }
}
